package com.gzhryc.shared_device.oem.code.member.services;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import com.gzhryc.common.NumberTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.jdbc.Conditions;
import com.gzhryc.jdbc.JdbcSession;
import com.gzhryc.jdbc.MultiDBTools;
import com.gzhryc.shared_device.base.enums.ELogState;
import com.gzhryc.shared_device.base.enums.ERefundState;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.base.models.OrderLogContent;
import com.gzhryc.shared_device.common.payment.dao.db.WXRefundOrder;
import com.gzhryc.shared_device.oem.code.member.dao.MemberRechargeOrderDao;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberRechargeOrder;
import com.gzhryc.shared_device.oem.code.member.dao.enums.MemberRechargeOrderEnum;
import com.gzhryc.shared_device.oem.code.member.services.dto.MemberRechargeOrderSearch;

public class MemberRechargeOrderService {

    static Logger log = Logger.getLogger(MemberRechargeOrderService.class);

    public static MemberRechargeOrderService self(Date date) {
        return MultiDBTools.getService(MemberRechargeOrderService.class, date);
    }

    public static MemberRechargeOrderService self(String jdbcKey,Date date) {
        return MultiDBTools.getService(jdbcKey, MemberRechargeOrderService.class, date);
    }

    MemberRechargeOrderDao dao;

    public MemberRechargeOrderService(String jdbcKey,Date date) {
        dao = new MemberRechargeOrderDao(jdbcKey,date);
    }

    public List<MemberRechargeOrder> findBySearch(MemberRechargeOrderSearch search, Integer pageNo, Integer pageLimit){
        Conditions conditions = dao.buildConditions(search);
        conditions.desc("createDate");
        try {
            return dao.findByCondition(conditions,pageNo,pageLimit);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public List<MemberRechargeOrder> findOldCanRefund(Long memberId,Integer payType){
        Conditions conditions = new Conditions(MemberRechargeOrder.class);
        conditions.and().is("memberId",memberId);
        conditions.and().is("sourceType",MemberRechargeOrderEnum.SourceType.Recharge.index());
        conditions.and().is("state", MemberRechargeOrderEnum.State.Success.index());
        conditions.and().is("operateState",MemberRechargeOrderEnum.OperateState.Normal.index());
        conditions.and().is("payType",payType);
        conditions.asc("createDate");

        try {
            return dao.findByCondition(conditions);
        } catch (SQLException e) {
            log.info(e.getMessage(),e);
        }
        return null;
    }

    public Long countBySearch(MemberRechargeOrderSearch search){
        Conditions conditions = dao.buildConditions(search);
        try {
            return dao.count(conditions);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public MemberRechargeOrder getByTradeNo(String tradeNo){
        try {
            return dao.getById(tradeNo);
        } catch (SQLException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    public boolean paySuccess(MemberRechargeOrder rechargeOrder, OrderLogContent orderLogContent, OperateInfo operateInfo){
        rechargeOrder.setState(MemberRechargeOrderEnum.State.Success.index());
        boolean flag = false;
        String errorMsg = null;
        JdbcSession.begin();
        try {
            if(dao.insert(rechargeOrder) > 0){
                //单位转化，分变厘
                Long tempMoney = NumberTools.changeMoneyLi(NumberTools.changeMoney(rechargeOrder.getMoney()));
                if(MemberWalletService.self().addMoney(rechargeOrder.getMemberId(),tempMoney,operateInfo)){
                    flag = true;
                    JdbcSession.commit();
                }
            }
        } catch (SQLException e) {
            errorMsg = e.getMessage();
            log.error(e.getMessage(),e);
        } catch (LogicException e) {
            errorMsg = e.getMessage();
            log.error(e.getMessage(),e);
        } finally {
            JdbcSession.end();
        }
        if(flag){
            //记录订单日志
            OrderLogContent.LogItem logItem = new OrderLogContent.LogItem();
            logItem.setCreateDate(new Date());
            if(StringTools.isNotBlank(operateInfo.getOperateNote())) {
                logItem.setContent(rechargeOrder.getPayTypeName() + "回调支付成功，系统充值成功，" + operateInfo.getOperateNote());
            }else{
                logItem.setContent(rechargeOrder.getPayTypeName() + "回调支付成功，系统充值成功");
            }
            logItem.setState(ELogState.Success.index());
            logItem.setProgramType(operateInfo.getProgramType());
            logItem.setProgramTypeName(operateInfo.getProgramTypeName());
            logItem.setOperatorType(operateInfo.getOperatorType());
            logItem.setOperatorTypeName(operateInfo.getOperatorTypeName());
            logItem.setOperator(operateInfo.getOperator());
            orderLogContent.getItems().add(logItem);
            MemberRechargeOrderLogService.self(rechargeOrder.getCreateDate()).add(rechargeOrder,orderLogContent);
            return true;
        }else{
            OrderLogContent.LogItem logItem = new OrderLogContent.LogItem();
            logItem.setCreateDate(new Date());
            if(StringTools.isNotBlank(operateInfo.getOperateNote())) {
                logItem.setContent(rechargeOrder.getPayTypeName() + "回调支付成功，系统充值失败，" + operateInfo.getOperateNote());
            }else{
                logItem.setContent(rechargeOrder.getPayTypeName() + "回调支付成功，系统充值失败");
            }
            logItem.setState(ELogState.Fail.index());
            logItem.setProgramType(operateInfo.getProgramType());
            logItem.setProgramTypeName(operateInfo.getProgramTypeName());
            logItem.setOperatorType(operateInfo.getOperatorType());
            logItem.setOperatorTypeName(operateInfo.getOperatorTypeName());
            logItem.setOperator(operateInfo.getOperator());
            if(StringTools.isBlank(errorMsg)){
                errorMsg = "系统错误";
            }
            logItem.setErrorMsg(errorMsg);
            MemberRechargeOrderLogService.self(rechargeOrder.getCreateDate()).add(rechargeOrder,orderLogContent);
        }
        return false;
    }

    public void refundResult(WXRefundOrder refundOrder, OperateInfo operateInfo) {
    	if (ERefundState.Success.index().equals(refundOrder.getRefundStatus())) {
        	MemberRechargeOrderService.self(refundOrder.getCreateDate()).updateRefundMoney(refundOrder.getBusinessTradeNo()
        			, refundOrder.getRefundMoney(),operateInfo);
        }else {
        	if(!MemberRechargeOrderService.self(refundOrder.getCreateDate()).toOperateRefundUnlock(refundOrder.getBusinessTradeNo())){
                log.error("修改{{0}}充值订单的退款操作状态失败",refundOrder.getBusinessTradeNo());
            }
        }
    	
    	//处理会员提现
    	MemberRechargeRefundOrderService.self().refundResult(refundOrder,operateInfo);
    }
    
    public boolean updateRefundMoney(String tradeNo,Integer refundMoney, OperateInfo operateInfo){
        if(StringTools.isNotBlank(tradeNo) && refundMoney != null){
            MemberRechargeOrder order = getByTradeNo(tradeNo);
            if(order != null && MemberRechargeOrderEnum.OperateState.Refunding.index().equals(order.getOperateState())) {
                Integer state = null;
                Integer totalRefundMoney = order.getRefundMoney() + refundMoney - 1;  //误差1分钱
                if (totalRefundMoney >= order.getPayMoney()) {
                    state = MemberRechargeOrderEnum.State.RefundFinish.index();
                }

                Conditions conditions = new Conditions(MemberRechargeOrder.class);
                conditions.and().is("tradeNo", tradeNo);
                conditions.and().is("operateState",MemberRechargeOrderEnum.OperateState.Refunding.index());

                MemberRechargeOrder updateEntity = new MemberRechargeOrder();
                updateEntity.setState(state);
                updateEntity.setRefundMoney(refundMoney);
                updateEntity.setOperateState(MemberRechargeOrderEnum.OperateState.Normal.index());

                Integer logState = ELogState.Fail.index();
                String errorMsg = "修改数据库中退款金额失败";
                try {
                    if(dao.updateNotNullAndInc(updateEntity, conditions,"refundMoney") > 0) {
                    	logState = ELogState.Success.index();
                    	errorMsg = null;
                    }
                } catch (SQLException e) {
                    log.info(e.getMessage(), e);
                    errorMsg = "SQL错误，信息：" + e.getMessage();
                }
                
                OrderLogContent.LogItem logItem = new OrderLogContent.LogItem();
                logItem.setCreateDate(new Date());
                logItem.setContent("修改退款金额，退款金额增加" + NumberTools.getMoneyStr(refundMoney) + "元");
                logItem.setState(logState);
                logItem.setErrorMsg(errorMsg);
                logItem.setProgramType(operateInfo.getProgramType());
                logItem.setProgramTypeName(operateInfo.getProgramTypeName());
                logItem.setOperatorType(operateInfo.getOperatorType());
                logItem.setOperatorTypeName(operateInfo.getOperatorTypeName());
                logItem.setOperator(operateInfo.getOperator());
        
                MemberRechargeOrderLogService.self(order.getCreateDate()).add(order.getTradeNo(), logItem);
                
                return ELogState.Success.index().equals(logState);
            }
        }
        return false;
    }

    public boolean updateState(String tradeNo,Integer state){
        if(StringTools.isNotBlank(tradeNo) && state != null){
            MemberRechargeOrder updateEntity = new MemberRechargeOrder();
            updateEntity.setTradeNo(tradeNo);
            updateEntity.setState(state);

            try {
                return dao.updateNotNull(updateEntity) > 0;
            } catch (SQLException e) {
                log.error(e.getMessage(),e);
            }
        }
        return false;
    }

    public boolean toOperateRefundLock(String tradeNo){
        if(StringTools.isNotBlank(tradeNo)){
            Conditions conditions = new Conditions(MemberRechargeOrder.class);
            conditions.and().is("tradeNo",tradeNo);
            conditions.and().is("operateState",MemberRechargeOrderEnum.OperateState.Normal.index());


            MemberRechargeOrder updateEntity = new MemberRechargeOrder();
            updateEntity.setOperateState(MemberRechargeOrderEnum.OperateState.Refunding.index());

            try {
                return dao.updateNotNull(updateEntity,conditions) > 0;
            } catch (SQLException e) {
                log.info(e.getMessage(), e);
            }
        }

        return false;
    }

    public boolean toOperateRefundUnlock(String tradeNo){
        if(StringTools.isNotBlank(tradeNo)){
            Conditions conditions = new Conditions(MemberRechargeOrder.class);
            conditions.and().is("tradeNo",tradeNo);
            conditions.and().is("operateState",MemberRechargeOrderEnum.OperateState.Refunding.index());


            MemberRechargeOrder updateEntity = new MemberRechargeOrder();
            updateEntity.setOperateState(MemberRechargeOrderEnum.OperateState.Normal.index());

            try {
                return dao.updateNotNull(updateEntity,conditions) > 0;
            } catch (SQLException e) {
                log.info(e.getMessage(), e);
            }
        }

        return false;
    }

}
